301.クラスベースの単一キャラ

クラスを使って、データと処理を一体化させます。これがOOPの本質です。

p5.js oop
Learning OOP Object Oriented Programming

ついにクラスの登場!オブジェクト指向プログラミングの核心部分です。

クラスとは

データ + 処理 を1つにまとめた「設計図」です。

class Circle {
  constructor() {
    this.pos = { x: random(width), y: random(height) };
    this.speed = { x: ..., y: ... };
    this.acceleration = 0.1;
  }

  update() {
    this.pos.x += this.speed.x;
    // ...
  }

  display() {
    ellipse(this.pos.x, this.pos.y, 10, 10);
  }
}

クラスとインスタンスの関係

クラス インスタンス
設計図・型紙 実際に作られたモノ
1つだけ定義 何個でも作れる
class Circle { } new Circle()

たとえ話: クラスは「たい焼きの型」、インスタンスは「焼き上がったたい焼き」です。

  • 型(クラス)は1つでも、たい焼き(インスタンス)は何個でも作れる
  • すべてのたい焼きは同じ形だが、中身(データ)は違ってもよい

インスタンスの作成と使用

// インスタンス作成(new で設計図から実体を作る)
obj = new Circle();

// メソッド呼び出し(そのインスタンス固有の処理)
obj.update();
obj.display();

new キーワードで「設計図から実体を作る」というイメージです。

何が良いのか

  • データ(pos, speed)と処理(update, display)が一体化
  • new で何個でもインスタンスを作れる
  • 各インスタンスが自分のデータを持ち、自分で処理できる
  • コードの見通しが良くなる

次の302で、複数のインスタンスを配列で管理してみましょう。

View Source Code

let W, H, PW, PH;
const PADDING_RATIO = 0.2;
const MAX_SPEED = 10;

let obj;

class Circle {
  constructor() {
    this.pos = {
      x: random(width),
      y: random(height),
    };
    this.speed = {
      x: (Math.random() - 0.5) * MAX_SPEED,
      y: (Math.random() - 0.5) * MAX_SPEED,
    };
    this.acceleration = 0.1;
  }

  update() {
    this.pos.x += this.speed.x;
    this.pos.y += this.speed.y;

    if (this.pos.x < 0 + PW) {
      this.speed.x += this.acceleration;
    } else if (this.pos.x > W - PW) {
      this.speed.x -= this.acceleration;
    }

    if (this.pos.y < 0 + PH) {
      this.speed.y += this.acceleration;
    } else if (this.pos.y > H - PH) {
      this.speed.y -= this.acceleration;
    }
  }

  display() {
    stroke(0);
    fill(0);
    ellipse(this.pos.x, this.pos.y, 10, 10);
    text(["1:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 10, this.pos.y + 10);
  }
}

// main

function setup() {
  createCanvas((W = windowWidth), (H = windowHeight));
  PW = W * PADDING_RATIO;
  PH = H * PADDING_RATIO;

  obj = new Circle()
}

function draw() {
  background(255);

  obj.update();
  obj.display();
}